from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from django.db import connection
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
import json
import os
import math
import datetime
import re
import uuid
import mimetypes
from pathlib import Path

# Create your views here.

# 公共方法 - 将查询结果转换为字典列表
def dictfetchall(cursor):
    """将游标返回的结果转换为字典"""
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
    ]

# 辅助函数 - 处理JSON响应
def json_response(data, status=200):
    """返回JSON格式响应"""
    return JsonResponse(data, status=status, json_dumps_params={'ensure_ascii': False})

@csrf_exempt
def resource_list(request):
    """获取资源列表(支持分页和筛选)"""
    if request.method == 'GET':
        try:
            # 获取查询参数
            page = int(request.GET.get('page', 1))
            page_size = int(request.GET.get('page_size', 10))
            name = request.GET.get('name', '')
            resource_type = request.GET.get('type', '')
            category_id = request.GET.get('category_id', '')
            sort_by = request.GET.get('sort_by', 'create_time')
            sort_order = request.GET.get('sort_order', 'desc')
            
            # 构建查询条件
            query = 'SELECT * FROM yzh_resource WHERE 1=1'
            count_query = 'SELECT COUNT(*) as total FROM yzh_resource WHERE 1=1'
            params = []
            
            if name:
                query += " AND name LIKE %s"
                count_query += " AND name LIKE %s"
                params.append(f'%{name}%')
            
            if resource_type:
                query += " AND type = %s"
                count_query += " AND type = %s"
                params.append(resource_type)
            
            if category_id:
                query += " AND category_id = %s"
                count_query += " AND category_id = %s"
                params.append(category_id)
            
            # 添加排序
            order = 'ASC' if sort_order.lower() == 'asc' else 'DESC'
            query += f" ORDER BY {sort_by} {order}"
            
            # 添加分页
            offset = (page - 1) * page_size
            query += " LIMIT %s OFFSET %s"
            limit_params = params.copy()
            limit_params.extend([page_size, offset])
            
            # 执行查询
            with connection.cursor() as cursor:
                cursor.execute(count_query, params)
                total = cursor.fetchone()[0]
                
                cursor.execute(query, limit_params)
                resources = dictfetchall(cursor)
                
                # 格式化日期时间
                for resource in resources:
                    if 'create_time' in resource and resource['create_time']:
                        if isinstance(resource['create_time'], datetime.datetime):
                            resource['create_time'] = resource['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                    if 'update_time' in resource and resource['update_time']:
                        if isinstance(resource['update_time'], datetime.datetime):
                            resource['update_time'] = resource['update_time'].strftime('%Y-%m-%d %H:%M:%S')
            
            return json_response({
                'status': 'success',
                'data': {
                    'items': resources,
                    'total': total,
                    'page': page,
                    'page_size': page_size,
                    'total_pages': math.ceil(total / page_size)
                }
            })
        except Exception as e:
            return json_response({
                'status': 'error',
                'message': f'获取资源列表失败: {str(e)}'
            }, 500)
    
    return json_response({
        'status': 'error',
        'message': '不支持的请求方法'
    }, 405)

@csrf_exempt
def resource_detail(request, resource_id):
    """获取、更新或删除指定资源"""
    try:
        # 检查资源是否存在
        with connection.cursor() as cursor:
            cursor.execute('SELECT * FROM yzh_resource WHERE id = %s', [resource_id])
            result = dictfetchall(cursor)
            
            if not result:
                return json_response({
                    'status': 'error',
                    'message': '资源不存在'
                }, 404)
            
            resource = result[0]
            
            # 格式化日期时间
            if 'create_time' in resource and resource['create_time']:
                if isinstance(resource['create_time'], datetime.datetime):
                    resource['create_time'] = resource['create_time'].strftime('%Y-%m-%d %H:%M:%S')
            if 'update_time' in resource and resource['update_time']:
                if isinstance(resource['update_time'], datetime.datetime):
                    resource['update_time'] = resource['update_time'].strftime('%Y-%m-%d %H:%M:%S')
        
        # 获取资源详情
        if request.method == 'GET':
            return json_response({
                'status': 'success',
                'data': resource
            })
        
        # 更新资源
        elif request.method == 'PUT':
            data = json.loads(request.body)
            name = data.get('name')
            category_id = data.get('category_id')
            resource_type = data.get('type')
            description = data.get('description')
            
            # 构建更新字段
            update_fields = {}
            params = []
            
            if name:
                update_fields['name'] = '%s'
                params.append(name)
            
            if category_id:
                # 查询分类名称
                with connection.cursor() as cursor:
                    cursor.execute('SELECT name FROM yzh_resource_category WHERE id = %s', [category_id])
                    category_result = cursor.fetchone()
                    
                    if category_result:
                        category_name = category_result[0]
                        update_fields['category_id'] = '%s'
                        update_fields['category_name'] = '%s'
                        params.extend([category_id, category_name])
            
            if resource_type:
                update_fields['type'] = '%s'
                params.append(resource_type)
            
            if 'description' in data:
                update_fields['description'] = '%s'
                params.append(description)
            
            # 如果没有要更新的字段，直接返回成功
            if not update_fields:
                return json_response({
                    'status': 'success',
                    'message': '资源信息未发生变化',
                    'data': resource
                })
            
            # 构建SQL语句
            set_clause = ', '.join([f'{key} = %s' for key in update_fields.keys()])
            query = f'UPDATE yzh_resource SET {set_clause} WHERE id = %s'
            params.append(resource_id)
            
            # 执行更新
            with connection.cursor() as cursor:
                cursor.execute(query, params)
                
                if cursor.rowcount > 0:
                    # 获取更新后的资源信息
                    cursor.execute('SELECT * FROM yzh_resource WHERE id = %s', [resource_id])
                    updated_resource = dictfetchall(cursor)[0]
                    
                    # 格式化日期时间
                    if 'create_time' in updated_resource and updated_resource['create_time']:
                        if isinstance(updated_resource['create_time'], datetime.datetime):
                            updated_resource['create_time'] = updated_resource['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                    if 'update_time' in updated_resource and updated_resource['update_time']:
                        if isinstance(updated_resource['update_time'], datetime.datetime):
                            updated_resource['update_time'] = updated_resource['update_time'].strftime('%Y-%m-%d %H:%M:%S')
                    
                    return json_response({
                        'status': 'success',
                        'message': '资源信息更新成功',
                        'data': updated_resource
                    })
                else:
                    return json_response({
                        'status': 'error',
                        'message': '资源信息更新失败'
                    }, 500)
        
        # 删除资源
        elif request.method == 'DELETE':
            # 先保存文件路径
            file_path = resource.get('path', '')
            
            # 删除数据库记录
            with connection.cursor() as cursor:
                cursor.execute('DELETE FROM yzh_resource WHERE id = %s', [resource_id])
                
                if cursor.rowcount > 0:
                    # 尝试删除文件
                    if file_path and os.path.exists(file_path):
                        try:
                            os.remove(file_path)
                        except Exception as e:
                            # 记录错误但不影响API响应
                            print(f"删除文件失败: {file_path} - {str(e)}")
                    
                    return json_response({
                        'status': 'success',
                        'message': '资源删除成功'
                    })
                else:
                    return json_response({
                        'status': 'error',
                        'message': '资源删除失败'
                    }, 500)
        
        return json_response({
            'status': 'error',
            'message': '不支持的请求方法'
        }, 405)
    
    except Exception as e:
        return json_response({
            'status': 'error',
            'message': f'操作资源失败: {str(e)}'
        }, 500)

@csrf_exempt
def resource_upload(request):
    """上传资源文件"""
    if request.method == 'POST':
        try:
            # 获取表单数据
            name = request.POST.get('name', '')
            category_id = request.POST.get('category_id', '1')
            resource_type = request.POST.get('type', 'document')
            description = request.POST.get('description', '')
            
            # 打印上传参数，便于调试
            print(f"文件上传请求参数: name={name}, category_id={category_id}, type={resource_type}")
            
            # 校验必要字段
            if not name:
                return json_response({
                    'status': 'error',
                    'message': '请提供资源名称'
                }, 400)
            
            # 检查是否上传了文件
            if 'file' not in request.FILES:
                return json_response({
                    'status': 'error',
                    'message': '请选择要上传的文件'
                }, 400)
            
            # 保存文件
            file = request.FILES['file']
            
            # 获取文件名和扩展名
            original_filename = file.name
            file_size = file.size
            
            print(f"上传文件: {original_filename}, 大小: {file_size} 字节")
            
            # 创建资源目录 - 使用绝对路径
            # 使用固定的绝对路径H:\毕业设计\resource_files
            resource_dir = 'H:\\毕业设计\\resource_files'
            
            # 确保目录存在
            print(f"尝试创建资源目录: {resource_dir}")
            try:
                os.makedirs(resource_dir, exist_ok=True)
                print(f"资源目录创建成功或已存在: {resource_dir}")
            except Exception as e:
                print(f"创建资源目录失败: {str(e)}")
                # 尝试备用路径
                resource_dir = os.path.abspath(os.path.join(settings.BASE_DIR, '..', 'resource_files'))
                print(f"尝试使用备用绝对路径: {resource_dir}")
                os.makedirs(resource_dir, exist_ok=True)
            
            # 保存文件
            file_path = os.path.join(resource_dir, original_filename)
            print(f"准备保存文件到: {file_path}")
            
            try:
                with open(file_path, 'wb+') as destination:
                    for chunk in file.chunks():
                        destination.write(chunk)
                print(f"文件成功保存到: {file_path}")
            except Exception as e:
                print(f"保存文件出错: {str(e)}")
                return json_response({
                    'status': 'error',
                    'message': f'保存文件失败: {str(e)}'
                }, 500)
            
            # 获取分类名称
            category_name = '教学课件'  # 默认分类名
            try:
                with connection.cursor() as cursor:
                    cursor.execute('SELECT name FROM yzh_resource_category WHERE id = %s', [category_id])
                    category_result = cursor.fetchone()
                    
                    if category_result:
                        category_name = category_result[0]
                    else:
                        print(f"未找到分类ID为 {category_id} 的分类，使用默认分类名")
            except Exception as e:
                print(f"获取分类名称出错: {str(e)}")
            
            # 如果没有提供描述，则生成默认描述
            if not description:
                description = f"通过API上传的{resource_type}类型资源"
            
            try:
                # 插入资源记录
                with connection.cursor() as cursor:
                    print("准备插入资源记录到数据库")
                    cursor.execute('''
                        INSERT INTO yzh_resource 
                        (name, category_id, category_name, type, path, size, description, creator_id) 
                        VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                    ''', [
                        name, 
                        category_id, 
                        category_name, 
                        resource_type, 
                        file_path, 
                        file_size, 
                        description, 
                        0  # 默认创建者ID为0
                    ])
                    
                    # 获取新插入记录的ID
                    cursor.execute('SELECT LAST_INSERT_ID()')
                    resource_id = cursor.fetchone()[0]
                    print(f"资源记录已插入，ID: {resource_id}")
                    
                    # 查询新插入的记录
                    cursor.execute('SELECT * FROM yzh_resource WHERE id = %s', [resource_id])
                    new_resource = dictfetchall(cursor)[0]
                    
                    # 格式化日期时间
                    if 'create_time' in new_resource and new_resource['create_time']:
                        if isinstance(new_resource['create_time'], datetime.datetime):
                            new_resource['create_time'] = new_resource['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                    if 'update_time' in new_resource and new_resource['update_time']:
                        if isinstance(new_resource['update_time'], datetime.datetime):
                            new_resource['update_time'] = new_resource['update_time'].strftime('%Y-%m-%d %H:%M:%S')
                    
                    return json_response({
                        'status': 'success',
                        'message': '资源上传成功',
                        'data': new_resource
                    }, 201)
            except Exception as e:
                print(f"数据库操作失败: {str(e)}")
                # 如果数据库操作失败，但文件已上传，则尝试删除已上传的文件
                if os.path.exists(file_path):
                    try:
                        os.remove(file_path)
                        print(f"由于数据库错误，已删除上传的文件: {file_path}")
                    except:
                        print(f"无法删除文件: {file_path}")
                
                return json_response({
                    'status': 'error',
                    'message': f'保存资源记录失败: {str(e)}'
                }, 500)
        
        except Exception as e:
            print(f"上传资源过程中出现异常: {str(e)}")
            return json_response({
                'status': 'error',
                'message': f'上传资源失败: {str(e)}'
            }, 500)
    
    return json_response({
        'status': 'error',
        'message': '不支持的请求方法'
    }, 405)

def resource_download(request, resource_id):
    """下载资源文件"""
    try:
        # 获取资源信息
        with connection.cursor() as cursor:
            cursor.execute('SELECT * FROM yzh_resource WHERE id = %s', [resource_id])
            result = dictfetchall(cursor)
            
            if not result:
                return json_response({
                    'status': 'error',
                    'message': '资源不存在'
                }, 404)
            
            resource = result[0]
            
            # 获取文件路径
            file_path = resource.get('path', '')
            
            # 检查文件是否存在
            if not os.path.exists(file_path):
                return json_response({
                    'status': 'error',
                    'message': '资源文件不存在'
                }, 404)
            
            # 更新下载次数
            cursor.execute('UPDATE yzh_resource SET download_count = download_count + 1 WHERE id = %s', [resource_id])
            
            # 获取文件名和MIME类型
            file_name = os.path.basename(file_path)
            content_type, encoding = mimetypes.guess_type(file_path)
            content_type = content_type or 'application/octet-stream'
            
            # 读取文件内容
            with open(file_path, 'rb') as f:
                response = HttpResponse(f.read(), content_type=content_type)
                
                # 设置下载头
                response['Content-Disposition'] = f'attachment; filename="{file_name}"'
                
                return response
    
    except Exception as e:
        return json_response({
            'status': 'error',
            'message': f'下载资源失败: {str(e)}'
        }, 500)

def resource_categories(request):
    """获取资源分类列表"""
    try:
        with connection.cursor() as cursor:
            cursor.execute('SELECT * FROM yzh_resource_category ORDER BY id ASC')
            categories = dictfetchall(cursor)
            
            # 格式化日期时间
            for category in categories:
                if 'create_time' in category and category['create_time']:
                    if isinstance(category['create_time'], datetime.datetime):
                        category['create_time'] = category['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                if 'update_time' in category and category['update_time']:
                    if isinstance(category['update_time'], datetime.datetime):
                        category['update_time'] = category['update_time'].strftime('%Y-%m-%d %H:%M:%S')
            
            return json_response({
                'status': 'success',
                'data': categories
            })
    
    except Exception as e:
        return json_response({
            'status': 'error',
            'message': f'获取分类列表失败: {str(e)}'
        }, 500)
